#include <iostream>

using std::cout;
using std::endl;

//y + 目标行 + G
class Base
{
public:
    Base(long base = 0)
    : _base(base)
    {
        cout << "Base(long = 0)" << endl;
    }

    virtual 
    void fun()
    {
        cout << "void Base::fun()" << endl;
    }

    virtual 
    void gun()
    {
        cout << "void Base::gun()" << endl;
    }

    virtual 
    void hun()
    {
        cout << "void Base::hun()" << endl;
    }

    ~Base()
    {
        cout << "~Base()" << endl;
    }
private:
    long _base;
};

class Derived
: public Base
{
public:
    Derived(long base = 0, long derived = 0)
    : Base(base)
    , _derived(derived)
    {
        cout << "Derived(long = 0, long = 0)" << endl;
    }

    virtual 
    void fun()
    {
        cout << "void Derived::fun()" << endl;
    }

    virtual 
    void gun()
    {
        cout << "void Derived::gun()" << endl;
    }

    virtual 
    void hun()
    {
        cout << "void Derived::hun()" << endl;
    }

    ~Derived()
    {
        cout << "~Derived()" << endl;
    }
private:
    long _derived;
};

int add(int x, int y)
{
    cout << "int add(int, int)" << endl;
    return x + y;
}

int func1()
{
    cout << "int func1()" << endl;
    return 10;
}

void test0()
{
    typedef int (*pFunc)(int, int);
    pFunc f = &add;
    cout <<"f(3, 4) = " << f(3, 4) << endl;

    cout << endl;
    typedef int (*Func)();
    Func g = func1;
    cout << "g() = " << g() << endl;

    /* g = add;//error */
}

void test()
{
    //虚表是存在的,对于普通单继承而言，虚表只有一张，是被该类
    //的所有对象共享的，存在只读段
    Derived derived(100, 200);
    printf("打印对象derived的地址: %p\n", &derived);
    printf("打印对象derived的地址: %p\n", (long *)&derived);
    printf("打印虚表的地址: %p\n", 
           (long *)*(long *)&derived);
           /* *&derived); */
    printf("打印第一个虚函数入口地址: %p\n", 
           (long *)*(long *)*(long *)&derived);

    cout << endl << endl;
    //typedef int A;
    typedef void (*pFunc)() ;
    pFunc f = (pFunc)* ((long *)*(long *)&derived);
    f();//函数的调用
    printf("打印第一个虚函数的入口地址: %p\n", f);

    cout << endl;
    f = (pFunc)* ((long *)*(long *)&derived + 1);
    f();//调用函数
    printf("打印第二个虚函数的入口地址: %p\n", f);

    cout << endl;
    f = (pFunc)* ((long *)*(long *)&derived + 2);
    f();//调用函数
    printf("打印第三个虚函数的入口地址: %p\n", f);

    cout << endl;
    Derived derived2(10, 20);
    printf("打印对象derived2的地址: %p\n", &derived2);
    printf("打印对象derived2的地址: %p\n", (long *)&derived2);
    printf("打印虚表的地址: %p\n", 
           (long *)*(long *)&derived2);
    printf("打印第一个虚函数入口地址: %p\n", 
           (long *)*(long *)*(long *)&derived2);

    cout << endl << "打印私有数据成员的值" << endl;
    cout << "_base = " << (long)*((long *)&derived + 1) << endl;
    cout << "_derived = " << (long)*((long *)&derived + 2) << endl;
}

int main(int argc, char *argv[])
{
    test();
    return 0;
}

